home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / fadeflip / texture.c++ < prev    next >
C/C++ Source or Header  |  1996-11-11  |  21KB  |  815 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include "texture.h"
  39.  
  40. extern "C" {
  41. #include "myimage.h"
  42. };
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <limits.h>
  47. #include <malloc.h>
  48.  
  49. #define Malloc(ptr, type, count) \
  50. { \
  51.   ptr = (type *)malloc(count * sizeof(type)); \
  52.   if (ptr == NULL && count != 0 && sizeof(type) != 0) { \
  53.     fprintf(stderr, "malloc failed.\n"); \
  54.     fprintf(stderr, "%d bytes requested.\n", count * sizeof(type)); \
  55.     exit(1); \
  56.   } \
  57. }
  58.  
  59. inline int sizeof_format(GLenum format) 
  60. {
  61.   switch(format) {
  62.   case GL_COLOR_INDEX:
  63.   case GL_RED:
  64.   case GL_GREEN:
  65.   case GL_BLUE:
  66.   case GL_ALPHA:
  67.   case GL_LUMINANCE:
  68.     return 1;
  69.   case GL_LUMINANCE_ALPHA:
  70.     return 2;
  71.   case GL_RGB:
  72.     return 3;
  73.   case GL_RGBA:
  74.     return 4;
  75.   default:
  76.     fprintf(stderr, "Unrecognized pixel format %d.\n", format);
  77.     return 0;
  78.   }
  79. }
  80.  
  81. inline int sizeof_type(GLenum type)
  82. {
  83.   switch(type) {
  84.   case GL_UNSIGNED_BYTE:
  85.     return sizeof(GLubyte);
  86.   case GL_BYTE:
  87.     return sizeof(GLbyte);
  88.   case GL_UNSIGNED_SHORT:
  89.     return sizeof(GLushort);
  90.   case GL_SHORT:
  91.     return sizeof(GLshort);
  92.   case GL_UNSIGNED_INT:
  93.     return sizeof(GLuint);
  94.   case GL_INT:
  95.     return sizeof(GLint);
  96.   default:
  97.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  98.     return 0;
  99.   }
  100. }
  101.  
  102. inline float max_value(GLenum type)
  103. {
  104.   switch(type) {
  105.   case GL_UNSIGNED_BYTE:
  106.     return 255.0;
  107.   case GL_BYTE:
  108.     return 127.0;
  109.   case GL_UNSIGNED_SHORT:
  110.     return 65535.0;
  111.   case GL_SHORT:
  112.     return 32767.0;
  113.   case GL_UNSIGNED_INT:
  114.     return 4294967295.0;
  115.   case GL_INT:
  116.     return 2147483647.0;
  117.   default:
  118.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  119.     return 0;
  120.   }
  121. }
  122.  
  123. inline float max_value_inv(GLenum type)
  124. {
  125.   switch(type) {
  126.   case GL_UNSIGNED_BYTE:
  127.     return 3.9215686e-3;
  128.   case GL_BYTE:
  129.     return 7.8740157e-3;
  130.   case GL_UNSIGNED_SHORT:
  131.     return 1.5259022e-5;
  132.   case GL_SHORT:
  133.     return 3.0518509e-5;
  134.   case GL_UNSIGNED_INT:
  135.     return 2.3283064e-10;
  136.   case GL_INT:
  137.     return 4.46566129e-10;
  138.   default:
  139.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  140.     return 0;
  141.   }
  142. }
  143.  
  144. inline float luminance(float r, float g, float b) 
  145. {
  146.   return(.299*r + .587*g + .114*b);
  147. }
  148.  
  149. texture::texture() 
  150. {
  151. }
  152.  
  153. void texture::open()
  154. {
  155.   pixels = NULL;
  156.   pixels_size = 0;
  157.   display_format = DEFAULT_DISPLAY_FORMAT;
  158.   display_type = DEFAULT_DISPLAY_TYPE;
  159.   alignment = DEFAULT_ALIGNMENT;
  160.   components = DEFAULT_COMPONENTS;
  161.   level = DEFAULT_LEVEL;
  162.   
  163.   min_filter = DEFAULT_MIN_FILTER;
  164.   max_filter = DEFAULT_MAX_FILTER;
  165.  
  166.   environment = DEFAULT_ENVIRONMENT;
  167.  
  168. }
  169.  
  170. void texture::set_display_format(GLenum new_display_format)
  171. {
  172.   reformat(new_display_format, display_type, alignment);
  173. }
  174.  
  175. GLenum texture::get_display_format()
  176. {
  177.   return display_format;
  178. }
  179.  
  180. void texture::set_display_type(GLenum new_display_type)
  181. {
  182.   reformat(display_format, new_display_type, alignment);
  183. }
  184.  
  185. GLenum texture::get_display_type()
  186. {
  187.   return display_type;
  188. }
  189.  
  190. void texture::set_alignment(int new_alignment)
  191. {
  192.   reformat(display_format, display_type, new_alignment);
  193. }
  194.  
  195. int texture::get_alignment()
  196. {
  197.   return alignment;
  198. }
  199.  
  200. void texture::set_components(int new_components)
  201. {
  202.   components = new_components;
  203. }
  204.  
  205. int texture::get_components()
  206. {
  207.   return components;
  208. }
  209.  
  210. void texture::set_level(int new_level)
  211. {
  212.   level = new_level;
  213. }
  214.  
  215. int texture::get_level()
  216. {
  217.   return level;
  218. }
  219.  
  220. void texture::set_min_filter(GLenum new_min_filter) 
  221. {
  222.   min_filter = new_min_filter;
  223. }
  224.  
  225. GLenum texture::get_min_filter() 
  226. {
  227.   return min_filter;
  228. }
  229.  
  230. void texture::set_max_filter(GLenum new_max_filter)
  231. {
  232.   max_filter = new_max_filter;
  233. }
  234.  
  235. GLenum texture::get_max_filter()
  236. {
  237.   return max_filter;
  238. }
  239.  
  240. int texture::get_width()
  241. {
  242.   return width;
  243. }
  244.  
  245. int texture::get_height()
  246. {
  247.   return height;
  248. }
  249.  
  250. void texture::set_environment(GLenum new_environment)
  251. {
  252.   environment = new_environment;
  253. }
  254.  
  255. GLenum texture::get_environment()
  256. {
  257.   return environment;
  258. }
  259.  
  260. void texture::create_color(int total_size,
  261.                float r, float g, float b, float a, float l)
  262. {
  263.   int x, y;
  264.   width = height = total_size;
  265.   pixels_alloc(width * height);
  266.   for (y = 0; y < height; y++)
  267.     for (x = 0; x < width; x++)
  268.       assign_pixel(x, y, r, g, b, a, l);
  269. }
  270.  
  271. void texture::create_checkerboard(int total_size, int block_size,
  272.                   float r1, float g1, float b1,
  273.                   float alpha1, float lum1,
  274.                   float r2, float g2, float b2,
  275.                   float alpha2, float lum2) 
  276. {
  277.   int x, y;
  278.   width = height = total_size;
  279.   pixels_alloc(width * height);
  280.   for (y = 0; y < height; y++)
  281.     for (x = 0; x < width; x++)
  282.       if ((((x /block_size) % 2) + ((y / block_size) % 2)) % 2)
  283.     assign_pixel(x, y, r1, g1, b1, alpha1, lum1);
  284.       else assign_pixel(x, y, r2, g2, b2, alpha2, lum2);
  285. }
  286.  
  287. void texture::create_diag_stripes(int total_size, int stripe_width,
  288.                   float r1, float g1, float b1,
  289.                   float alpha1, float lum1,
  290.                   float r2, float g2, float b2,
  291.                   float alpha2, float lum2) 
  292.  
  293. {
  294.   int x, y;
  295.   width = height = total_size;
  296.   pixels_alloc(width * height);
  297.   for (y = 0; y < height; y++)
  298.     for (x = 0; x < width; x++)
  299.       if (((x + y) / stripe_width) % 2) 
  300.     assign_pixel(x, y, r1, g1, b1, alpha1, lum1);
  301.       else assign_pixel(x, y, r2, g2, b2, alpha2, lum2);
  302. }
  303.  
  304. void texture::create_from_file(char *fname) 
  305. {
  306.   IMAGE *image;
  307.   unsigned short *rbuf, *gbuf, *bbuf;
  308.   float r, g, b;
  309.   int x, y;
  310.  
  311.   image = iopen(fname, "r");
  312.   if (image == NULL) {
  313.     fprintf(stderr, "Unable to open file %s.\n", fname);
  314.     exit(1);
  315.   }
  316.  
  317.   width = image->xsize;
  318.   height = image->ysize;
  319.  
  320.   Malloc(rbuf, unsigned short, image->xsize);
  321.   Malloc(gbuf, unsigned short, image->xsize);
  322.   Malloc(bbuf, unsigned short, image->xsize);
  323.  
  324.   pixels_alloc(width * height);
  325.  
  326.   for (y = 0; y < image->ysize; y++) {
  327.     getrow(image, rbuf, y, 0);
  328.     getrow(image, gbuf, y, 1);
  329.     getrow(image, bbuf, y, 2);
  330.     for (x = 0; x < image->xsize; x++) {
  331.       r = (float)rbuf[x] / 255.0;
  332.       g = (float)gbuf[x] / 255.0;
  333.       b = (float)bbuf[x] / 255.0;
  334.       assign_pixel(x, y, r, g, b, 1.0, luminance(r, g, b));
  335.     }
  336.   }
  337.  
  338.   if (image->xsize) {
  339.     free(rbuf);
  340.     free(gbuf);
  341.     free(bbuf);
  342.   }
  343.  
  344.   /* There must be some way to close an image file, but I don't know
  345.    * know what it is, so we'll just leave it open for now. */
  346.  
  347. }
  348.  
  349. void texture::map_lum_to_alpha() 
  350. {
  351.   int x, y;
  352.   float lum;
  353.  
  354.   if (pixels_size == 0) {
  355.     fprintf(stderr, "Cannot map luminance to alpha:  no image in memory.\n");
  356.     return;
  357.   }
  358.   for (y = 0; y < height; y++)
  359.     for (x = 0; x < width; x++) 
  360.       assign_pixel_a(x, y, pixel_lum(x, y));
  361. }
  362.  
  363. void texture::draw_pixels()
  364. {
  365.   draw_pixels(0, 0, width, height);
  366. }
  367.  
  368. void texture::draw_pixels(int x1, int y1, int x2, int y2)
  369. {
  370.   glPixelStorei(GL_PACK_ROW_LENGTH, width);
  371.   glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  372.   glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); 
  373.   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
  374.   glDrawPixels(x2-x1, y2-y1, display_format, display_type, pixels);
  375. }
  376.  
  377. void texture::setup_texture() 
  378. {
  379.   setup_texture(0, 0, width, height);
  380. }
  381.  
  382. void texture::setup_texture(int x1, int y1, int x2, int y2)
  383. {
  384.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
  385.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
  386.  
  387.   if ((components < 3 && environment == GL_DECAL) || 
  388.       (components > 2 && environment == GL_BLEND)) 
  389.     fprintf(stderr, 
  390.         "Warning:  illegal component / environment combination.\n");
  391.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, environment);
  392.  
  393.   glPixelStorei(GL_PACK_ROW_LENGTH, width);
  394.   glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  395.   glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
  396.   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 
  397. }
  398.  
  399. void texture::specify_texture()
  400. {
  401.   specify_texture(0, 0, width, height);
  402. }
  403.  
  404.  
  405. void texture::specify_texture(int x1, int y1, int x2, int y2)
  406. {
  407.   setup_texture(x1, y1, x2, y2);
  408.  
  409.   /* Create the mip map if required, otherwise don't */
  410.   if (min_filter == GL_NEAREST || min_filter == GL_LINEAR) 
  411.     glTexImage2D(GL_TEXTURE_2D, level, components,
  412.          x2-x1, y2-y1, 0, display_format, display_type,
  413.          pixels);
  414.   else gluBuild2DMipmaps(GL_TEXTURE_2D, components, x2-x1,
  415.              y2-y1, display_format, display_type,
  416.              pixels);
  417. }
  418.  
  419. void texture::specify_mipmap() 
  420. {
  421.   specify_mipmap(0, 0, width, height);
  422. }
  423.  
  424. void texture::specify_mipmap(int x1, int y1, int x2, int y2)
  425. {
  426.   glTexImage2D(GL_TEXTURE_2D, level, components, 
  427.            x2-x1, y2-y1, 0, display_format, display_type,
  428.            pixels);
  429. }
  430.  
  431. void texture::pixels_alloc() 
  432. {
  433.   pixels_alloc(height * width);
  434. }
  435.  
  436. void texture::pixels_alloc(int size)
  437. {
  438.   int size_bytes;
  439.  
  440.   size_bytes = 
  441.     size * sizeof_format(display_format) * sizeof_type(display_type);
  442.   if (pixels_size == 0) {
  443.     pixels = malloc(size_bytes);
  444.     pixels_size = size_bytes;
  445.   }
  446.   else if (size_bytes > pixels_size) {
  447.     pixels = realloc(pixels, size_bytes);
  448.     pixels_size = size_bytes;
  449.   }
  450.   if (pixels == NULL && size_bytes != 0) {
  451.     fprintf(stderr, "Malloc failed - unable to allocate %d bytes.\n",
  452.         size_bytes);
  453.     exit(1);
  454.   }
  455.   
  456. }
  457.  
  458. void texture::pixels_free()
  459. {
  460.   if (pixels != NULL) free(pixels);
  461.   pixels = NULL;
  462.   pixels_size = 0;
  463. }
  464.  
  465. #define ASSIGN_PIXEL2(element, value, el_length, enum, type) \
  466.  case enum: \
  467.   ((type *)((char *)pixels + y*rowlength))[x*el_length + element] = \
  468.   (type)(value * max_value(enum)); \
  469. break; 
  470.  
  471. #define ASSIGN_PIXEL(element, value, el_length) \
  472. switch(display_type) { \
  473.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_BYTE, GLubyte); \
  474.   ASSIGN_PIXEL2(element, value, el_length, GL_BYTE, GLbyte); \
  475.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_SHORT, GLushort); \
  476.   ASSIGN_PIXEL2(element, value, el_length, GL_SHORT, GLshort); \
  477.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_INT, GLuint); \
  478.   ASSIGN_PIXEL2(element, value, el_length, GL_INT, GLint); \
  479. }
  480.  
  481. void texture::assign_pixel(int x, int y, float r, float g, float b, float a,
  482.                float l)
  483. {
  484.   assign_pixel(x, y, r, g, b, a, l, display_format, display_type, alignment);
  485. }
  486.  
  487. void texture::assign_pixel(int x, int y, float r, float g, float b, float a,
  488.                float l, GLenum display_format, 
  489.                GLenum display_type, int alignment)
  490. {
  491.   int rowlength;
  492.  
  493.   rowlength = row_length();
  494.   switch (display_format) {
  495.   case GL_RED:
  496.     ASSIGN_PIXEL(0, r, 1);
  497.     break;
  498.   case GL_GREEN:
  499.     ASSIGN_PIXEL(0, g, 1);
  500.     break;
  501.   case GL_BLUE:
  502.     ASSIGN_PIXEL(0, b, 1);
  503.     break;
  504.   case GL_ALPHA:
  505.     ASSIGN_PIXEL(0, a, 1);
  506.     break;
  507.   case GL_LUMINANCE:
  508.     ASSIGN_PIXEL(0, l, 1);
  509.     break;
  510.   case GL_LUMINANCE_ALPHA:
  511.     ASSIGN_PIXEL(0, l, 2);
  512.     ASSIGN_PIXEL(1, a, 2);
  513.     break;
  514.   case GL_RGB:
  515.     ASSIGN_PIXEL(0, r, 3);
  516.     ASSIGN_PIXEL(1, g, 3);
  517.     ASSIGN_PIXEL(2, b, 3);
  518.     break;
  519.   case GL_RGBA:
  520.     ASSIGN_PIXEL(0, r, 4);
  521.     ASSIGN_PIXEL(1, g, 4);
  522.     ASSIGN_PIXEL(2, b, 4);
  523.     ASSIGN_PIXEL(3, a, 4);
  524.     break;
  525.   default:
  526.     fprintf(stderr, "Unrecognized display format %d\n", display_format);
  527.     exit(1);
  528.   }
  529. }
  530.  
  531. inline void texture::assign_pixel_a(int x, int y, float a)
  532. {
  533.   int rowlength = row_length();
  534.   if (display_format == GL_LUMINANCE_ALPHA) {
  535.     ASSIGN_PIXEL(1, a, 2); 
  536.   } else if (display_format == GL_RGBA) ASSIGN_PIXEL(3, a, 4);
  537.   return;
  538. }
  539.  
  540. void texture::reformat(GLenum new_display_format, GLenum new_display_type,
  541.                int new_alignment)
  542. {
  543.   GLenum old_display_format = display_format;
  544.   GLenum old_display_type = display_type;
  545.   int old_alignment = alignment;
  546.   int old_pixels_size = pixels_size;
  547.   int direction;
  548.   int old_rowlength, new_rowlength;
  549.   int x, y;
  550.   
  551.   /* Make sure that something acutally has changed. */
  552.   if (new_display_format == old_display_format &&
  553.       new_display_type == old_display_type && 
  554.       new_alignment == old_alignment) return;
  555.  
  556.   if (old_pixels_size == 0) {
  557.     display_format = new_display_format;
  558.     display_type = new_display_type;
  559.     alignment = new_alignment;
  560.     return;
  561.   }
  562.  
  563.   old_rowlength = row_length(old_display_format, old_display_type,
  564.                  old_alignment);
  565.   new_rowlength = row_length(new_display_format, new_display_type,
  566.                  new_alignment);
  567.   
  568.   /* Seems like this should cause a core dump since the amount of 
  569.    * space has not changed yet... */
  570.   pixels_alloc();
  571.  
  572.   if (new_rowlength > old_rowlength) direction = -1;
  573.   else direction = 1;
  574.  
  575.   for (y = (direction == 1 ? 0 : height - 1);
  576.        y < height && y >= 0; y += direction) 
  577.     for (x = (direction == 1 ? 0 : width - 1);
  578.          x < height && x >= 0; x += direction) 
  579.       {
  580.     assign_pixel(x, y, pixel_r(x, y), pixel_g(x, y), pixel_b(x, y),
  581.              pixel_alpha(x, y), pixel_lum(x, y), new_display_format,
  582.              new_display_type, new_alignment);
  583.       }
  584.  
  585.   display_format = new_display_format;
  586.   display_type = new_display_type;
  587.   alignment = new_alignment;
  588.  
  589. }
  590.  
  591. int texture::row_length()
  592. {
  593.   return row_length(display_format, display_type, alignment);
  594. }
  595.  
  596. int texture::row_length(GLenum display_format, GLenum display_type,
  597.             int alignment)
  598. {
  599.   int row_length;
  600.   row_length = width * sizeof_format(display_format) * 
  601.     sizeof_type(display_type);
  602.   row_length += row_length % alignment;
  603.   return row_length;
  604. }
  605.  
  606. #define PIXEL_VALUE2(enum, type, index) \
  607. ((float) \
  608. ((type *)((char *)pixels + y*rowlength)) \
  609. [x*sizeof_format(display_format) + index] * max_value_inv(enum))
  610.  
  611. #define PIXEL_VALUE(enum, type, index) \
  612.  case enum: \
  613.   return PIXEL_VALUE2(enum, type, index);
  614.  
  615. #define PIXEL_AVG_VALUE(enum, type) \
  616.  case enum: \
  617.   return (luminance(PIXEL_VALUE2(enum, type, 0), \
  618.             PIXEL_VALUE2(enum, type, 1), \
  619.             PIXEL_VALUE2(enum, type, 2)));
  620.  
  621. inline float texture::pixel_r(int x, int y)
  622. {
  623.   return pixel_r(x, y, display_format, display_type, alignment);
  624. }
  625.  
  626. inline float texture::pixel_r(int x, int y, GLenum display_format, 
  627.   GLenum display_type, int alignment)
  628. {
  629.   int rowlength;
  630.   
  631.   rowlength = row_length(display_format, display_type, alignment);
  632.  
  633.   switch(display_format) {
  634.   case GL_RED:
  635.   case GL_RGB:
  636.   case GL_RGBA:
  637.   case GL_LUMINANCE:
  638.   case GL_LUMINANCE_ALPHA:
  639.     switch(display_type) {
  640.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  641.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  642.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  643.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  644.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  645.       PIXEL_VALUE(GL_INT, GLint, 0);
  646.     }
  647.     break;
  648.   case GL_GREEN:
  649.   case GL_BLUE:
  650.     return 0.0;
  651.   }
  652. }
  653.  
  654. inline float texture::pixel_g(int x, int y)
  655. {
  656.   return pixel_g(x, y, display_format, display_type, alignment);
  657. }
  658.  
  659. inline float texture::pixel_g(int x, int y, GLenum display_format, 
  660.                    GLenum display_type, int alignment)
  661. {
  662.   int rowlength;
  663.   
  664.   rowlength = row_length(display_format, display_type, alignment);
  665.  
  666.   switch(display_format) {
  667.   case GL_GREEN:
  668.   case GL_LUMINANCE:
  669.   case GL_LUMINANCE_ALPHA:
  670.     switch(display_type) {
  671.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  672.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  673.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  674.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  675.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  676.       PIXEL_VALUE(GL_INT, GLint, 0);
  677.     }
  678.     break;
  679.   case GL_RGB:
  680.   case GL_RGBA:
  681.     switch(display_type) {
  682.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 1);
  683.       PIXEL_VALUE(GL_BYTE, GLbyte, 1);
  684.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 1);
  685.       PIXEL_VALUE(GL_SHORT, GLshort, 1);
  686.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 1);
  687.       PIXEL_VALUE(GL_INT, GLint, 1);
  688.     }
  689.     break;
  690.   case GL_RED:
  691.   case GL_BLUE:
  692.     return 0.0;
  693.   }
  694. }
  695.  
  696. inline float texture::pixel_b(int x, int y)
  697. {
  698.   return pixel_b(x, y, display_format, display_type, alignment);
  699. }
  700.  
  701. inline float texture::pixel_b(int x, int y, GLenum display_format, 
  702.                    GLenum display_type, int alignment)
  703. {
  704.   int rowlength;
  705.   
  706.   rowlength = row_length(display_format, display_type, alignment);
  707.  
  708.   switch(display_format) {
  709.   case GL_BLUE:
  710.   case GL_LUMINANCE:
  711.   case GL_LUMINANCE_ALPHA:
  712.     switch(display_type) {
  713.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  714.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  715.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  716.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  717.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  718.       PIXEL_VALUE(GL_INT, GLint, 0);
  719.     }
  720.     break;
  721.   case GL_RGB:
  722.   case GL_RGBA:
  723.     switch(display_type) {
  724.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 2);
  725.       PIXEL_VALUE(GL_BYTE, GLbyte, 2);
  726.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 2);
  727.       PIXEL_VALUE(GL_SHORT, GLshort, 2);
  728.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 2);
  729.       PIXEL_VALUE(GL_INT, GLint, 2);
  730.     }
  731.     break;
  732.   case GL_RED:
  733.   case GL_GREEN:
  734.     return 0.0;
  735.   }
  736. }
  737.  
  738. inline float texture::pixel_alpha(int x, int y)
  739. {
  740.   return pixel_alpha(x, y, display_format, display_type, alignment);
  741. }
  742.  
  743. inline float texture::pixel_alpha(int x, int y, GLenum display_format, 
  744.                    GLenum display_type, int alignment)
  745. {
  746.   int rowlength;
  747.  
  748.   rowlength = row_length(display_format, display_type, alignment);
  749.   switch(display_format) {
  750.   case GL_RGBA:
  751.     switch(display_type) {
  752.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 3);
  753.       PIXEL_VALUE(GL_BYTE, GLbyte, 3);
  754.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 3);
  755.       PIXEL_VALUE(GL_SHORT, GLshort, 3);
  756.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 3);
  757.       PIXEL_VALUE(GL_INT, GLint, 3);
  758.     }
  759.   case GL_LUMINANCE_ALPHA:
  760.     switch(display_type) {
  761.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 1);
  762.       PIXEL_VALUE(GL_BYTE, GLbyte, 1);
  763.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 1);
  764.       PIXEL_VALUE(GL_SHORT, GLshort, 1);
  765.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 1);
  766.       PIXEL_VALUE(GL_INT, GLint, 1);
  767.     }
  768.   default:
  769.     return 1.0;
  770.   }
  771. }
  772.  
  773. inline float texture::pixel_lum(int x, int y)
  774. {
  775.   return pixel_lum(x, y, display_format, display_type, alignment);
  776. }
  777.  
  778. inline float texture::pixel_lum(int x, int y, GLenum display_format, 
  779.                 GLenum display_type, int alignment)
  780. {
  781.   int rowlength;
  782.  
  783.   rowlength = row_length(display_format, display_type, alignment);
  784.  
  785.   switch(display_format) {
  786.   case GL_RED:
  787.   case GL_GREEN:
  788.   case GL_BLUE:
  789.   case GL_LUMINANCE:
  790.   case GL_LUMINANCE_ALPHA:
  791.     switch(display_type) {
  792.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  793.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  794.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  795.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  796.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  797.       PIXEL_VALUE(GL_INT, GLint, 0);
  798.     }
  799.     break;
  800.   case GL_RGB:
  801.   case GL_RGBA:
  802.     switch(display_type) {
  803.       PIXEL_AVG_VALUE(GL_UNSIGNED_BYTE, GLubyte);
  804.       PIXEL_AVG_VALUE(GL_BYTE, GLbyte);
  805.       PIXEL_AVG_VALUE(GL_UNSIGNED_SHORT, GLushort);
  806.       PIXEL_AVG_VALUE(GL_SHORT, GLshort);
  807.       PIXEL_AVG_VALUE(GL_UNSIGNED_INT, GLuint);
  808.       PIXEL_AVG_VALUE(GL_INT, GLint);
  809.     }
  810.   default:
  811.     fprintf(stderr, "Unrecognized display format %d\n", display_format);
  812.     return 0.0;
  813.   }
  814. }
  815.